package cn.com.surker.base.strength.service.impl;

import cn.com.surker.base.strength.dao.BaseStrengthDao;
import cn.com.surker.base.strength.dao.BaseStrengthOrgDao;
import cn.com.surker.base.strength.entity.BaseStrength;
import cn.com.surker.base.strength.entity.BaseStrengthOrg;
import cn.com.surker.base.strength.service.StrengthBaseService;
import cn.com.surker.base.strength.vo.BaseStrengthVo;
import cn.com.surker.common.MessageCenterException;
import cn.com.surker.database.JDBCTemplateCache;
import cn.com.surker.dto.main.BaseStrengthQueryDTO;
import cn.com.surker.enums.mes.MemberTypeEnum;
import cn.com.surker.enums.system.DataBaseEnum;
import cn.com.surker.enums.system.StrengthTypeEnum;
import cn.com.surker.spring.RestResultDto;
import cn.com.surker.system.dao.DataSourceInfoDao;
import cn.com.surker.system.dao.SysUserDao;
import cn.com.surker.system.entity.DataSourceInfo;
import cn.com.surker.system.entity.SysUser;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.MathUtils;
import cn.com.surker.util.StringUtils;
import cn.com.surker.vo.strength.BaseStrengthVO;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author lucky
 * @create 2024年07月17 14:41
 * @desc
 */
public abstract class StrengthBaseServiceImpl extends ServiceImpl<BaseStrengthDao, BaseStrength> implements StrengthBaseService {

    @Resource
	protected BaseStrengthDao baseStrengthDao;
    @Resource
	protected BaseStrengthOrgDao baseStrengthOrgDao;
    @Resource
	protected DataSourceInfoDao dsDao;
    @Resource
	protected SysUserDao sysUserDao;


	/**
	 * 根据公司关联标号分页查询
	 * @param searchVal
	 * @param orgId
	 * @param type
	 * @param offset
	 * @param limit
	 * @return
	 */
	public IPage findPageV1(String searchVal, Long orgId, Integer type, Integer status, Integer offset, Integer limit) {
		if (StringUtils.isNull(status))
			status = 0;
		PageHelper.offsetPage(offset, limit);
		IPage<BaseStrengthVo> iPage = baseStrengthDao.findPage(new Page<>((offset + limit) /limit, limit),
				searchVal, type, status, orgId);
		/**分页插件**/
		if (!StringUtils.isNull(iPage.getRecords())) {
			PageInfo pageInfo = new PageInfo(iPage.getRecords());
			if (!StringUtils.isNull(pageInfo.getTotal()))
				iPage.setTotal(pageInfo.getTotal());
		}
		return iPage;
	}
	/**
	 * 添加关联公司信息
	 * @param id 标号ID
	 * @param orgId
	 * @param isInfo
	 * @param isDisplay
	 * @param remark
	 * @param creator
	 * @return
	 */
	public RestResultDto saveV1(Long id, Long orgId, Integer isInfo, Integer isDisplay, Integer transportType, String remark, String creator) {
		if (StringUtils.isNull(id))
			throw new MessageCenterException("强度等级参数错误");
		if (StringUtils.isNull(orgId))
			throw new MessageCenterException("公司信息错误");
		if (StringUtils.isNull(isInfo))
			isInfo = 0;
		if (StringUtils.isNull(isDisplay))
			isDisplay = 0;
		BaseStrength strength = baseStrengthDao.selectById(id);
		if (strength == null || strength.getStatus() == 1)
			throw new MessageCenterException("强度等级信息不存在或已被禁用");
		QueryWrapper<BaseStrengthOrg> query = new QueryWrapper<>();
		query.eq("org_id", orgId);
		query.eq("strength_id", id);
		query.eq("status", 0);
		Integer total = baseStrengthOrgDao.selectCount(query);
		if (total > 0)
			throw new MessageCenterException("已有关联数据,请勿重新关联");
		DataSourceInfo ds = dsDao.queryDSByOriginIdV1(orgId, DataBaseEnum.MYSQL.getCode());
		if (ds == null || ds.getStatus() == 1)
			throw new MessageCenterException("公司数据源不存在或已被禁用");
		Date nowDate = new Date();
		BaseStrengthOrg strengthOrg = new BaseStrengthOrg(orgId, null, id, 0, remark, creator, nowDate);
		strengthOrg.setTransportType(transportType);
		strengthOrg.setIsDisplay(isDisplay);
		strengthOrg.setIsInfo(isInfo);
		Integer code = baseStrengthOrgDao.insert(strengthOrg);
		if (code > 0) {
			if (ds.getType().intValue() == 0) {
				String insertSql = "insert into base_strength_org (id,org_id,is_info,is_display,strength_id,status," +
						"creator,create_time) values(?,?,?,?,?,?,?,?)";
				Object[] objs = {strengthOrg.getId(),orgId,isInfo,isDisplay,id,0,creator, DateUtil.convertString(nowDate)};
				JdbcTemplate jdbcTemplate = JDBCTemplateCache.getLocalJdbcTemplate(ds);
				jdbcTemplate.update(insertSql, objs);
			}

			return RestResultDto.success("保存成功", strengthOrg);
		}
		throw new MessageCenterException("新增公司强度信息错误");
	}

	/**
	 * 修改标号信息
	 * @param id
	 * @param isInfo
	 * @param isDisplay
	 * @param remark
	 * @param creator
	 * @return
	 */
	public RestResultDto updateV1(Long id, Long orgId, Integer isInfo, Integer isDisplay, Integer transportType, String remark, String creator) {
		if (StringUtils.isNull(id))
			throw new MessageCenterException("强度等级参数错误");
		if (StringUtils.isNull(isInfo))
			isInfo = 0;
		if (StringUtils.isNull(isDisplay))
			isDisplay = 0;
		QueryWrapper<BaseStrengthOrg> query = new QueryWrapper<>();
		query.eq("status", 0);
		query.eq("org_id", orgId);
		query.eq("strength_id", id);
		query.orderByDesc("id");
		List<BaseStrengthOrg> orgList = baseStrengthOrgDao.selectList(query);
		if (orgId == null || orgList.size() == 0)
			throw new MessageCenterException("强度等级信息不存在或已被禁用");
		BaseStrengthOrg strengthOrg = orgList.get(0);
		if (strengthOrg == null || strengthOrg.getStatus() == 1)
		strengthOrg.setIsInfo(isInfo);
		strengthOrg.setIsDisplay(isDisplay);
		if (!StringUtils.isNull(remark))
			strengthOrg.setRemark(remark);
		strengthOrg.setTransportType(transportType);
		strengthOrg.setUpdator(creator);
		strengthOrg.setUpdateTime(new Date());
		Integer code = baseStrengthOrgDao.updateById(strengthOrg);
		if (code > 1)
			return RestResultDto.success("更新成功", strengthOrg);
		throw new MessageCenterException("修改公司强度信息错误");
	}

	public BaseStrengthVo findById(Long id) {
		if (StringUtils.isNull(id))
			return null;
		BaseStrengthVo vo = baseStrengthDao.selectByIdVo(id);
		return vo;
	}
	/**
	 * 分页查询标号
	 * @param searchVal
	 * @param offset
	 * @param limit
	 * @return
	 */
	public IPage findPage(String searchVal, Integer type, Integer offset, Integer limit) {
		PageHelper.offsetPage(offset, limit);
		QueryWrapper<BaseStrength> query = new QueryWrapper<>();
		if (!StringUtils.isNull(searchVal)) {
			query.and(orderWrapper -> orderWrapper.like("strength", searchVal).or()
					.like("remark", searchVal));
		}
        if (!StringUtils.isNull(type))
            query.eq("type", type);
		query.orderByDesc("id");

		IPage<BaseStrength> iPage = baseStrengthDao.selectPage(new Page<>((offset + limit) /limit, limit), query);
		/**分页插件**/
		if (!StringUtils.isNull(iPage.getRecords())) {
			PageInfo pageInfo = new PageInfo(iPage.getRecords());
			if (!StringUtils.isNull(pageInfo.getTotal()))
				iPage.setTotal(pageInfo.getTotal());
		}
		return iPage;
	}

//	@Cacheable(cacheNames = "strengthCache")
    public List<BaseStrength> findAll() {//
        QueryWrapper<BaseStrength> query = new QueryWrapper<>();
        query.eq("status", 0);
        query.orderByAsc("strength");
        List<BaseStrength> list = baseStrengthDao.selectList(query);
        if (list == null || list.size() == 0)
            return null;
        return list;
    }

	/**
	 * 根据公司ID查询标号
	 * @param orgId
	 * @return
	 */
//	@Cacheable(cacheNames = "strengthCache", key = "#orgId")
	public List<BaseStrength> findByOrg(Long orgId) {
		if (StringUtils.isNull(orgId))
			return null;
		QueryWrapper<BaseStrength> query = new QueryWrapper<>();
		query.eq("status", 0);
		query.inSql("id", "select strength_id from base_strength_org where org_id = " + orgId + " and status = 0");
		query.orderByAsc("strength");
		List<BaseStrength> list = baseStrengthDao.selectList(query);
		if (list == null || list.size() == 0) {
			return null;
		}
		return list;
	}

	@Cacheable(cacheNames = "strengthCache", key = "#strength == null ? '' : #strength")
	public List<BaseStrength> findList(String strength) {
		QueryWrapper<BaseStrength> query = new QueryWrapper<>();
		query.eq("status", 0);
		if (StringUtils.isNotBlank(strength)) {
			query.like("strength", strength);
		}
		query.orderByAsc("strength");
		List<BaseStrength> list = baseStrengthDao.selectList(query);
		if (list == null || list.size() == 0) {
			return null;
		}
		return list;
	}

	@Override
	public BaseStrength findByErpId(Long originId, Long erpId) {
		return baseStrengthDao.findByErpId(originId, erpId);
	}
	public BaseStrengthOrg findByErpStrength(Long originId, Long strengthId) {
    	QueryWrapper<BaseStrengthOrg> query = new QueryWrapper<>();
    	query.eq("org_id", originId);
    	query.eq("status", 0);
    	query.eq("strength_id", strengthId);
    	query.orderByDesc("id");
    	List<BaseStrengthOrg> list = baseStrengthOrgDao.selectList(query);
    	if (list == null || list.size() == 0)
    		return null;
    	return list.get(0);
	}

	@Override
	public List<BaseStrength> findBySaleCon(Long conId) {
		if (conId == null) {
			return null;
		}
		List<BaseStrength> strengthList = baseStrengthDao.findByContract(conId);
		return strengthList;
	}


	/**
	 * 保存强度等级
	 * @param baseStrength
	 * @return
	 */
    @CacheEvict(value = "strengthCache", allEntries = true)
	public RestResultDto saveStrength(BaseStrength baseStrength) {
		if (baseStrength == null)
			return RestResultDto.fail("参数错误");
		if (StringUtils.isNull(baseStrength.getDosage()) || baseStrength.getDosage() < 100)
			baseStrength.setDosage(2350.0);//默认容重
		String strength = baseStrength.getLevel();
		if (!StringUtils.isNull(baseStrength.getType())) {
			if (baseStrength.getType().intValue() == StrengthTypeEnum.PC.getCode()) {
				if (baseStrength.getMemberType() == null || baseStrength.getMemberType() == -1)
					throw new MessageCenterException("PC构件产品必须选择构件类型");
				String memberType = "";
				for (int i = 0; i < MemberTypeEnum.values().length; i++) {
					if (baseStrength.getMemberType() == MemberTypeEnum.values()[i].getCode()) {
						memberType = MemberTypeEnum.values()[i].getDescription();
						break;
					}
				}
				if (StringUtils.isNull(memberType))
					throw new MessageCenterException("PC构件类型未知");
				strength = memberType + "[" + strength + "]";
			} else {
				if (!StringUtils.isNull(baseStrength.getPermeability()))
					strength += baseStrength.getPermeability().toUpperCase().replaceAll(" ", "");
				if (!StringUtils.isNull(baseStrength.getBending()))
					strength += baseStrength.getBending().toUpperCase().replaceAll(" ", "");
				if (!StringUtils.isNull(baseStrength.getFreeze()))
					strength += baseStrength.getFreeze().toUpperCase().replaceAll(" ", "");
				if (!StringUtils.isNull(baseStrength.getMaterialRequirement()))
					strength += baseStrength.getMaterialRequirement().toUpperCase().replaceAll(" ", "");
				if (!StringUtils.isNull(baseStrength.getTechnologyRequirement()))
					strength += baseStrength.getTechnologyRequirement().toUpperCase().replaceAll(" ", "");
			}
		}

		BaseStrength tempStrength = baseStrengthDao.findExistStrength(strength);
		if (tempStrength != null)
			return RestResultDto.fail("该标号已存在~！");
		baseStrength.setStrength(strength);
		baseStrength.setCreateTime(new Date());
		baseStrength.setStatus(0);
		Integer code = baseStrengthDao.insert(baseStrength);
		if (code > 0)
			return RestResultDto.success("保存成功");
		return RestResultDto.fail("保存失败");
	}

	/**
	 * 更新强度等级
	 * @param baseStrength
	 * @return
	 */
//    @CacheEvict(value = "strengthCache", allEntries = true)
	public RestResultDto updateStrength(BaseStrength baseStrength) {
		if (baseStrength == null || StringUtils.isNull(baseStrength.getId()))
			return RestResultDto.fail("参数错误");
		BaseStrength updateStrength = baseStrengthDao.selectById(baseStrength.getId());
		if (updateStrength == null)
			return RestResultDto.fail("修改标号不存在");
		SysUser user = sysUserDao.queryByName(baseStrength.getUpdator());
		if(user == null || user.getStatus() == 1)
			return RestResultDto.fail("您的账户不存在或已禁用");
		QueryWrapper<BaseStrengthOrg> orgQuery = new QueryWrapper<>();
		orgQuery.eq("status", 0);
		orgQuery.eq("strength_id", baseStrength.getId());
		orgQuery.inSql("org_id", "select org_id from sys_origin_role where uid = 2 and status = 0 group by org_id");
		Integer total = baseStrengthOrgDao.selectCount(orgQuery);
		if (total < 1)
			return RestResultDto.fail("该标号没有关联您所在工厂,没有修改权限");

		String strength = baseStrength.getLevel();
		if (!StringUtils.isNull(baseStrength.getType())) {
			if (baseStrength.getType().intValue() == StrengthTypeEnum.PC.getCode()) {
				if (baseStrength.getMemberType() == null || baseStrength.getMemberType() == -1)
					throw new MessageCenterException("PC构件产品必须选择构件类型");
				String memberType = "";
				for (int i = 0; i < MemberTypeEnum.values().length; i++) {
					if (baseStrength.getMemberType() == MemberTypeEnum.values()[i].getCode()) {
						memberType = MemberTypeEnum.values()[i].getDescription();
						break;
					}
				}
				if (StringUtils.isNull(memberType))
					throw new MessageCenterException("PC构件类型未知");
				strength = memberType + "[" + strength + "]";
			} else {
				if (!StringUtils.isNull(baseStrength.getPermeability()))
					strength += baseStrength.getPermeability().toUpperCase().replaceAll(" ", "");
				if (!StringUtils.isNull(baseStrength.getBending()))
					strength += baseStrength.getBending().toUpperCase().replaceAll(" ", "");
				if (!StringUtils.isNull(baseStrength.getFreeze()))
					strength += baseStrength.getFreeze().toUpperCase().replaceAll(" ", "");
				if (!StringUtils.isNull(baseStrength.getMaterialRequirement()))
					strength += baseStrength.getMaterialRequirement().toUpperCase().replaceAll(" ", "");
				if (!StringUtils.isNull(baseStrength.getTechnologyRequirement()))
					strength += baseStrength.getTechnologyRequirement().toUpperCase().replaceAll(" ", "");
			}
		}
		if (!StringUtils.isNull(strength) && !strength.equals(updateStrength.getStrength())) {
			BaseStrength tempStrength = baseStrengthDao.findExistStrength(strength);
			if (tempStrength != null)
				return RestResultDto.fail("该标号已存在~！");
		}

		baseStrength.setStrength(strength);
		baseStrength.setUpdateTime(new Date());
		Integer code = baseStrengthDao.updateById(baseStrength);
		if (code > 0)
			return RestResultDto.success("更新成功");
		return RestResultDto.fail("更新失败");
	}

    public IPage<BaseStrengthVO> pageData(BaseStrengthQueryDTO dto){
        PageHelper.offsetPage(dto.getOffsetSize(), dto.getLimit());
        Page<BaseStrength> page = new Page<>(dto.getCurrSize(), dto.getLimit());

        IPage<BaseStrengthVO> iPage = baseStrengthDao.pageData(page, dto);
        /**分页插件**/
        if (ObjectUtil.isNotEmpty(iPage)) {
            PageInfo pageInfo = new PageInfo(iPage.getRecords());
            if (!StringUtils.isNull(pageInfo.getTotal())) iPage.setTotal(pageInfo.getTotal());
        }
        return iPage;
    }

	/**
	 * 设置砼运输类型
	 * @param ids
	 * @param type transporttype 枚举
	 * @param creator
	 * @return
	 */
	public RestResultDto updateTransportType(String ids, Integer type, String creator) {
		if (StringUtils.isAllParamNull(ids, type))
			throw new MessageCenterException("参数错误");
		String[] ids_ = ids.split(",");
		if (ids_ == null || ids_.length == 0)
			throw new MessageCenterException("更新数据标识错误");
		UpdateWrapper<BaseStrength> uw = new UpdateWrapper<>();
		uw.set("transport_type", type);
		uw.set("update_time", DateUtil.convertString(new Date()));
		if (!StringUtils.isNull(creator))
			uw.set("updator", creator);
		uw.in("id", ids_);
		Integer code = baseStrengthDao.update(new BaseStrength(), uw);
		if (code > 0)
			return RestResultDto.success("更新成功");
		throw new MessageCenterException("更新错误");
	}
	/**
	 * 定时任务更新标号容重
	 * @return
	 */
	public RestResultDto updateLevelDosage() {
		QueryWrapper<DataSourceInfo> query = new QueryWrapper<>();
		query.eq("status", 0);
		query.eq("type", DataBaseEnum.MYSQL.getCode());
		List<DataSourceInfo> dsList = dsDao.selectList(query);
		if (dsList == null || dsList.size() == 0)
			return RestResultDto.fail("数据源不存在");
		Date nowDate = new Date();
		String time = DateUtil.convertString(DateUtil.convertBeforeDayDate(nowDate, 30));
		Map<Long, Double> strengthMap = new HashMap<>();
		for (DataSourceInfo ds : dsList) {
			try {
				List<BaseStrength> strengthList = baseStrengthDao.findLevelDosage(ds.getCode(), time);
				if (strengthList == null || strengthList.size() == 0)
					continue;
				for (BaseStrength baseStrength : strengthList) {
					Long strengthId = baseStrength.getId();
					Double dosage = baseStrength.getDosage();

					if (dosage < 1000 || dosage > 3200)
						continue;
					if (strengthMap.containsKey(strengthId)) {
						Double dosage_ = strengthMap.get(strengthId);
						if (dosage_ > dosage)
							strengthMap.put(strengthId, dosage_);
					} else {
						strengthMap.put(strengthId, dosage);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				continue;
			}
		}
		if (strengthMap == null || strengthMap.keySet().size() == 0)
			return RestResultDto.fail("没有需要更新的标号容重");
		for (Long strengthId : strengthMap.keySet()) {
			try {
				BaseStrength baseStrength = baseStrengthDao.selectById(strengthId);
				Double oldDosage = StringUtils.convertDouble(baseStrength.getDosage());
				Double calcValue = Math.abs(oldDosage - strengthMap.get(strengthId));
				calcValue = StringUtils.divideDouble(calcValue, oldDosage, 3) * 1000;
				if (calcValue > 8 || oldDosage < 1000 || oldDosage > 3200) {
					UpdateWrapper<BaseStrength> uw = new UpdateWrapper<>();
					uw.set("dosage", strengthMap.get(strengthId));
					uw.set("update_time", nowDate);
					uw.set("updator", "系统更新");
					uw.set("remark", "系统更新标号容重(原容重: + " + baseStrength.getDosage() + ")");
					uw.eq("id", strengthId);
					Integer code = baseStrengthDao.update(new BaseStrength(), uw);
				}
			} catch (Exception e) {
				e.printStackTrace();
				continue;
			}
		}
		return RestResultDto.success("更新标号容重成功");
	}
}
